//
// JavadocTool
//
// Copyright (C) jextra.net.
//
//  This file is part of the Crack build system.
//
//  The Crack build system is free software; you can redistribute it 
//  and/or modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  The Crack build system is distributed in the hope that it will be 
//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with the Crack build system; if not, write to the Free
//  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
//  02111-1307 USA.
//

package net.jextra.crack.tool;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import net.jextra.crack.*;
import net.jextra.crack.type.*;

/**
 * <p>
 * Wrapper tool to the javadoc application.
 * </p>
 */
public class JavadocTool
{
    // ============================================================
    // Fields
    // ============================================================

    private File outputDir;
    private String bootClassPath;

    // ============================================================
    // Methods
    // ============================================================

    // ----------
    // public
    // ----------

    public void setOutputDir( File dir )
    {
        assert dir.isDirectory() : "Output dir '" + dir + "' must be an existing directory";
        outputDir = dir;
    }

    public void setBootClassPath( String path )
    {
        bootClassPath = path;
    }

    public void execute( FileSet files )
        throws CrackException
    {
        ArrayList<String> args = new ArrayList<String>();
        try
        {
            if ( bootClassPath != null )
            {
                args.add( "-bootclasspath" );
                args.add( bootClassPath );
            }

            if ( outputDir != null )
            {
                System.out.printf( "Outputing javadoc to [%s]\n", outputDir.getAbsolutePath() );
                args.add( "-d" );
                args.add( outputDir.getCanonicalPath() );
            }

            for ( File file : files )
            {
                if ( file.getName().endsWith( ".java" ) )
                {
                    args.add( file.getCanonicalPath() );
                }
            }
        }
        catch ( IOException ex )
        {
            throw new CrackException( ex );
        }

        int result;
        try
        {
            result = executeInJVM( args );
        }
        catch ( Throwable ex )
        {
            ex.printStackTrace();

            result = -1;
        }

        assert result == 0 : "An error occured [" + result + "] while attempting to execute javadoc tool.";
    }

    // ----------
    // private
    // ----------

    private int executeInJVM( ArrayList<String> args )
        throws Exception
    {
        // Not sure why but javadoc must run on standard ClassLoader.
        Class<?> javacClass = getClass().getClassLoader().getParent().loadClass( "com.sun.tools.javadoc.Main" );
        Method method = javacClass.getMethod( "execute", new Class[]
        { String[].class } );
        method.setAccessible( true );

        String[] strings = new String[args.size()];
        for ( int i = 0; i < args.size(); i++ )
        {
            strings[i] = args.get( i );
        }

        int result = (Integer) method.invoke( null, new Object[]
        { strings } );

        //        int result = com.sun.tools.javadoc.Main.execute( strings );

        return result;
    }
}
